import { Asset, AudioClip, JsonAsset, Prefab, SpriteAtlas, 
    SpriteFrame,Node, Sprite, instantiate, Animation, 
    AnimationClip, AssetManager, Constructor, 
    error, assert, resources, isValid, TextAsset,Material,Mesh, } from "cc"
import { CSVManager } from "./CSVManager";
import { UserInfo } from "./UserInfo";
import { AudioMgr } from "./AudioMgr";

export class ResManager {
    private _Prefabs:Map<string,Prefab>  = new Map();//存储cc.Prefab类型的资源
    private _SpriteFrames:Map<string,SpriteFrame>  = new Map();
    private _SpriteAtlass:Map<string,SpriteAtlas>  = new Map();
    private _AudioClips:Map<string,AudioClip>  = new Map();
    private _Materials:Map<string,Material>  = new Map();
    
    // 数据 json文件
    private _JsonAssets:Map<string,JsonAsset>  = new Map();
    // 存储动画剪辑
    private _AnimationClips:Map<string,AnimationClip> = new Map();
   

    
    // 单例
    private static _instance:ResManager = null;
    private constructor(){}
    public static get Instance():ResManager{
        if (!this._instance) {
            this._instance = new ResManager();
            
        }
        return this._instance;
    }
    /**
     * @zh 加载resources下的所有资源 并存储到管理器内
     * @param onProgress 可选，用于监听加载进度的回调函数 可在回调中处理进度条
     */
    async loadAllResources(onProgress?:(finished: number, total: number, item: AssetManager.RequestItem) => void){
        try {
            const assets:Asset[] = await this.loadAll(onProgress) as Asset[];
            this.addRes(assets);
        } catch (error) {
            console.error('Error loading Res:', error);
        } 
    }
    

    private loadAll(onProgress?:(finished: number, total: number, item: AssetManager.RequestItem) => void){
        return new Promise((resolve, reject) => {
            resources.loadDir('',onProgress,(err, res) => {
            
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        }); 
    }


    /**
     * @en load and get Res.
     * @zh 异步加载单个文件资源 
    */
    private load(path:string){
        return new Promise((resolve, reject) => {
            resources.load(path, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        }); 
    }
 
    /**
     * @en load and get Res.
     * @zh 动态加载资源 调用此方法的函数请使用async修饰 在方法前加await关键字获取资源
     * @zh 资源必须在resources文件夹内，传入相对路径
     */
    async loadRes(path:string):Promise<Asset> {
        try {
            const res = await this.load(path);
            return res as Asset;
        } catch (error) {
            console.error('Error loading Res:'+ path, error);
            // 在这里处理加载资源失败的情况
            return null;
        }
    }

    /**
     * @en load and get Res.
     * @zh 异步加载文件夹资源 调用此方法的函数请使用async修饰 在方法前加await关键字获取资源
     * @zh 资源必须在resources文件夹内，传入相对路径
    */
    async loadDirRes(path:string):Promise<Asset[]> {
        try {
            const assets = await this.load(path);
            return assets as Asset[];
        } catch (error) {
            console.error('Error loading Res:'+ path, error);
            // 在这里处理加载资源失败的情况
            return null;
        }
    }



  

    // 方法
    // 存储资源
    

    
    addRes(assets:Asset[]){
        // 分类存储
        assets.forEach(asset => {
            if (asset instanceof TextAsset) {
                CSVManager.Instance.parseCSV(asset);
            }
            else if(asset instanceof Prefab){
                this._Prefabs.set(asset.name,asset);
            }
            else if(asset instanceof SpriteFrame){
                this._SpriteFrames.set(asset.name,asset);
            }
            else if(asset instanceof SpriteAtlas){
                this._SpriteAtlass.set(asset.name,asset);
            }
            else if(asset instanceof AudioClip){
                this._AudioClips.set(asset.name,asset);
            }
            else if(asset instanceof Material){
                this._Materials.set(asset.name,asset);
            }
           
            else if(asset instanceof JsonAsset){
                this._JsonAssets.set(asset.name,asset);
            }
            else if(asset instanceof AnimationClip){
                this._AnimationClips.set(asset.name,asset);
            }
           

        });
    }

    // 获取资源
    // 获取预制体资源
    getPrefab(name:string):Prefab{
        // map容器获取元素的方法
        return this._Prefabs.get(name);
    }
    // 获取图集atlas name携带plist后缀
    getAtlas(name:string):SpriteAtlas{
        return this._SpriteAtlass.get(name);
    }
    // 获取音频资源
    getAudioClip(name:string):AudioClip{
        return this._AudioClips.get(name);
    } 
    getAnimationClip(name:string):AnimationClip{
        return this._AnimationClips.get(name);
    } 
    getMaterial(name:string):Material{
        return this._Materials.get(name);
    } 
   
    getSpriteFrame(name:string):SpriteFrame{
        return this._SpriteFrames.get(name);
    }

    // 获取配置数据
    getJsonAsset(name:string):JsonAsset{
        return this._JsonAssets.get(name);
    }

    // 获取某个json的数据信息
    getAllData(name:string){
        const jsonAsset = this.getJsonAsset(name);
        if (jsonAsset) {
            return jsonAsset.json;
        }
        return null;
    }
    // 通过id获取数据
    getDataById(id:number|string,name:string){
        const datas = this.getAllData(name);
        if (datas) {
            // 如果数据存在 
            // 判断数据类型是对象还是数组
            if(Array.isArray(datas)){
                // 如果是数组 就遍历它 获取需要的id的数据
                for (const data of datas) {
                    if (data.id == id) {
                        return data;
                    }
                }
                return null;
            }
            // 不是数组 就按对象处理 直接判断id
            if (datas.id == id) {
                return datas;
            }
            return null;
        }
        return null;
    }

    
    /**
     * 
     * @param name 预制体名称,或者动态加载预制体的路径
     * @param parent 可选，实例化后挂载的父节点
     * @returns 返回该节点实例 请在调用前加上await关键字
     */
    async insPrefabaaa(name:string,parent?:Node){
        let pre:Prefab = this.getPrefab(name);
        if (!pre) {
            pre = await this.loadRes(name) as Prefab;
        }
        const node:Node = await instantiate(pre);
        parent && (node.parent = parent);
        return node;
    }
    insPrefab(name:string,parent?:Node){
        let pre:Prefab = this.getPrefab(name);
        
        const node:Node =  instantiate(pre);
        parent && (node.parent = parent);
        return node;
    }
    checkmusic(){
        if(UserInfo.Instance.music=='on'){
            AudioMgr.instance.play("BgMusic","long");
        }else{
            AudioMgr.instance.stop();
        }
        if(UserInfo.Instance.sound=='on'){
            AudioMgr.instance.changesound(1)
        }else{
            AudioMgr.instance.changesound(0)
        }
    }
    
    // obj  const {imgNames,node,name,mode,sample} = obj;
    // createAnimation(data:AnimationData):Animation{
    //     const {frameNames,node,aniName,mode,sample} = data;
    //     // 遍历名字 拿到所有精灵帧
    //     const frames:SpriteFrame[] = [];
    //     for (const name of frameNames) {
    //         const frame = this.getSpriteFrame(name);
    //         // 把数组中的所有名字对应的精灵帧  存储到frames中
    //         frames.push(frame);
    //     }
    //     // 添加动画组件
    //     const ani = node.addComponent(Animation);
    //     // 创建动画剪辑 （制作序列帧动画）
    //     const clip:AnimationClip = AnimationClip.createWithSpriteFrames(frames,sample);
    //     // 设置动画模式
    //     clip.wrapMode = mode;
    //     // 添加动画剪辑
    //     ani.addClip(clip,aniName);
    //     // 设置默认动画剪辑
    //     ani.defaultClip = clip;
    //     return ani;
    // }

    // createAnimaClip(clipData:AniClipData){
    //     const {id,frameNames,mode,sample} = clipData;
    //     // 创建动画剪辑 （制作序列帧动画）
    //      // 遍历名字 拿到所有精灵帧
    //     const frames:SpriteFrame[] = [];
    //     for (const name of frameNames) {
    //         const frame = this.getSpriteFrame(name);
    //         // 把数组中的所有名字对应的精灵帧  存储到frames中
    //         frames.push(frame);
    //     }
    //     const clip:AnimationClip = AnimationClip.createWithSpriteFrames(frames,sample);
    //     // 设置动画模式
    //     clip.wrapMode = mode;
    //     this._AnimationClips.set(id+'',clip);
    //     return clip;
    // }

    // getAnimationClip(name:string,clipData?:AniClipData):AnimationClip{
    //     let clip = this._AnimationClips.get(name);
    //     if (clip) {
    //         return clip;
    //     }
    //     return this.createAnimaClip(clipData);
    // }
}
